package smartcase.base

import org.springframework.context.ApplicationContext
import org.springframework.context.ApplicationContextAware
import org.springframework.stereotype.Component
import org.springframework.web.context.request.RequestContextHolder
import org.springframework.web.context.request.ServletRequestAttributes
import smartcase.base.access.LogCtx
import smartcase.common.constants.ProjectConstants.LOGCTX_INFO_KEY
import javax.servlet.ServletContextEvent
import javax.servlet.ServletContextListener
import javax.servlet.http.HttpServletRequest
import javax.servlet.http.HttpServletResponse
import kotlin.properties.Delegates

private lateinit var applicationContext: ApplicationContext
private var ctxStarted by Delegates.notNull<Boolean>()

@Component
open class ApplicationContextProvider : ApplicationContextAware, ServletContextListener {

    override fun setApplicationContext(ac: ApplicationContext) {
        applicationContext = ac
    }

    override fun contextInitialized(sce: ServletContextEvent?) {
        ctxStarted = true
    }
}

fun ctxIsStarted(): Boolean {
    return ctxStarted
}

fun <T> getBean(type: Class<T>): T = applicationContext.getBean(type)

fun getCommonInfoFromContext(): LogCtx? {
    val httpRequest = getHttpRequestFromContext() ?: return null
    return httpRequest.getAttribute(LOGCTX_INFO_KEY) as LogCtx?
}

fun getHttpRequestFromContext(): HttpServletRequest? {
    val attributes = RequestContextHolder.getRequestAttributes() ?: return null
    return if (attributes is ServletRequestAttributes) {
        attributes.request
    } else null
}

fun getHttpResponseFromContext(): HttpServletResponse? {
    val attributes = RequestContextHolder.getRequestAttributes() ?: return null
    return if (attributes is ServletRequestAttributes) {
        attributes.response
    } else null
}